package com.bblocks.common.anti_reptile.interceptor;


import com.bblocks.common.anti_reptile.annotation.AntiReptile;
import com.bblocks.common.anti_reptile.config.AntiReptileProperties;
import com.bblocks.common.anti_reptile.config.bean.RuleComm;
import com.bblocks.common.anti_reptile.module.MatchResult;
import com.bblocks.common.anti_reptile.rule.ResultStrategy;
import com.bblocks.common.anti_reptile.rule.RuleActuator;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 拦截器-顺序10
 * @author Jin
 * @since 2024/3/24
 */
public class AntiReptileInterceptor extends AbstractAntiInterceptor {

    @Resource
    private ResultStrategy resultStrategy;
    @Resource
    private RuleActuator actuator;
    @Resource
    private AntiReptileProperties antiReptileProperties;

    private List<String> includeUrls;

    private boolean globalFilterMode;


    @PostConstruct
    public void init() {
        this.includeUrls = antiReptileProperties.getIncludeUrls();
        this.globalFilterMode = antiReptileProperties.isGlobalFilterMode();
        if (this.includeUrls == null) {
            this.includeUrls = new ArrayList<>(0);
        }
    }

    @Override
    public boolean doPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HandlerMethod handlerMethod;
        try {
            handlerMethod = (HandlerMethod) handler;
        } catch (ClassCastException e) {
            return true;
        }
        Method method = handlerMethod.getMethod();
        AntiReptile antiReptile = AnnotationUtils.findAnnotation(method, AntiReptile.class);
        boolean isAntiReptileAnnotation = antiReptile != null;
        String requestUrl = request.getRequestURI();
        MatchResult matchResult = null;
        if (isIntercept(requestUrl, isAntiReptileAnnotation) && (matchResult = actuator.isAllowed(request, response)) != null) {
            resultStrategy.process(matchResult, request, response);
            return false;
        }
        return true;
    }

    public int getOrder(){
        return 10;
    }

    /**
     * 是否拦截
     * @param requestUrl 请求uri
     * @param isAntiReptileAnnotation 是否有AntiReptile注解
     * @return 是否拦截
     */
    public boolean isIntercept(String requestUrl, Boolean isAntiReptileAnnotation) {
        if (this.globalFilterMode || isAntiReptileAnnotation || this.includeUrls.contains(requestUrl)) {
            return true;
        } else {
            for (String includeUrl : includeUrls) {
                if (Pattern.matches(includeUrl, requestUrl)) {
                    return true;
                }
            }
            return false;
        }
    }
}
